#include "utils.h"
#include <QTextCodec>
#include<QtDebug>
#include <qmath.h>
#include <QTime>

Utils::Utils()
{

}

QByteArray Utils::unsignedToHexStr(unsigned short u)
{
    QString uStr =  QString::number(u,16);

    return QString("%1").arg(u, 4, 16, QLatin1Char('0')).toLatin1();
}

QByteArray Utils::unsignedToHexStr(unsigned  u )
{
    QString uStr =  QString::number(u,16);

    return QString("%1").arg(u, 8, 16, QLatin1Char('0')).toLatin1();
}

QByteArray Utils::unsignedToBinStr(unsigned u)
{
    return QString("%1").arg(u, 8, 16, QLatin1Char('0')).toLatin1();
}

QByteArray Utils::binStrToHexStr(QByteArray &binStr)
{
//    QByteArray b2 = "01000111";  //47, 低位节在右边
    int i = binStr.toInt(nullptr, 2);
    return decIntToBytes(i);        // 10进制数字转字符数组
}

QByteArray Utils::hexBytesToBin(QByteArray &hexBytes)
{
    QByteArray ret =  hexBytes.setNum(hexBytes.toInt(nullptr, 16) , 2);

    int emptyNum = 8 - ret.count();

    for (int i=0; i<emptyNum; i++) {
        ret.push_front('0');
    }

    return ret;

//     return QString("%1").arg(hexBytes.toUInt(nullptr, 16), 8, 16, QLatin1Char('0')).toLatin1();
}

QByteArray Utils::intToHexByte(int  u )
{
     QByteArray ret = QByteArray::number(u, 16);

     if( ret.count() ==1 ){
         ret.push_front('0');
     }

     return ret;
}

QByteArray Utils::decIntToBytes(int u)
{
    QByteArray ret = QByteArray::number(u);

    if ( ret.count() ==1){
        ret.push_front('0');
    }
    return  ret;
}


QString Utils::hexNumToDecNum(QString str)
{
    return QString::number(str.toUInt(nullptr,16));
}


//定值组  B6A8 D6B5 D7E9,  GB2312编码 , QString 是以 unicode 存储的, ASCII转为16进制字符 SSR530U->53 53 52 35 33 30 55
QString Utils::ChineseStrToHexStr(const QString &hexStr)
{    
    //QString ‐> GBK
    QByteArray bytes = hexStr.toLocal8Bit();
    const char*  gbk = bytes.toHex();

    return gbk;
}

// 将单个数字字符转换成 5 -> "05", 英文字母统一使用大写表示
QString Utils::number(const int intStr, int base)
{
    QString retStr =  QString::number(intStr,base=16).toUpper();
    //添加一个0在左边
    if (retStr.size()==1)
    {
        retStr.insert(0,"0");
    }

    return retStr;
}

QString Utils::gbk2Utf8(QString str)
{
    QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForLocale(utf8);

    QTextCodec *gbk = QTextCodec::codecForName("gbk");

    QString strUnicode = utf8->toUnicode(str.toLocal8Bit().data());
    QByteArray gbkBytes= gbk->fromUnicode(strUnicode);

    strUnicode=gbk->toUnicode(str.toLocal8Bit().data());
    QByteArray utf8Bytes=utf8->fromUnicode(strUnicode);

    if(WIN)
    {
        return  utf8Bytes;
    }
    else    //linux
    {
        return gbkBytes;
    }
}

QString Utils::GBKToUTF8(const QString &gbkStr)
{
    QTextCodec *tc = QTextCodec::codecForName("System");
    // 将Hex字符串转换为Ascii字符串
    QString temp;
    QByteArray ascii_data;
    QStringList temp_list = gbkStr.split(' ', QString::SkipEmptyParts);
    foreach(QString str, temp_list)
    {
        ascii_data.append(str);
    }
    // 将ascii_data中的16进制数据转化为对应的字符串，比如\x31转换为"1"
    temp = tc->toUnicode(QByteArray::fromHex(ascii_data));
    //qDebug() << gbkStr << " 转换为UTF8 ： " << temp;
    return temp;
}

void Utils::washPacket(QString &packet)
{
    packet.remove(" ");
    packet.remove(",");
}

void Utils::washPacket(QByteArray &packet)
{
    for (int i=0; i<packet.count(); i++)
    {
        if(packet[i] == ' ' || packet.at(i) == ',') {
            packet.remove(i, 1);
        }
    }
}


void Utils::hexStrToChinese(QString &hexStr)
{
    QTextCodec *codec = QTextCodec::codecForName("utf-8");
    QString str = "0891683108500145F1240D91685143256178F0000831214281659423044F60597D";
    QString t = str.mid(58);
    QStringList s;

    for(int i = 0;i < t.length();i += 4) {
        s.append(t.mid(i,4));
    }
    QString t1;

    foreach (const QString &t, s) {
        t1.append(t.toUShort(0,16));
    }

    QString re = codec->fromUnicode(t1);
    qDebug() << QObject::trUtf8(re.toLatin1().data());
}

void Utils::hexStrToChinese1(QString &hexStr)
{
    // 每个汉字用4个字母表示
    QString tmpStr;
    QByteArray tmpByteArray;
    QString retStr;
    for (int i=0; i<hexStr.length()/4; i+= 4)
    {
        tmpStr = hexStr.mid(i,4);
        tmpByteArray = tmpStr.toLocal8Bit();
        bool ok;
        QChar* unicode = new QChar[1];
        unicode[0] = tmpByteArray.toInt(&ok,16);
        QString str = QString::fromRawData(unicode,1);
        qDebug() << str;
        retStr.append(str);
    }
}

// gbk -> Chinese
void Utils::hexStrToChinese2(QString &hexStr)
{
    QString tmpStr;
    QByteArray tmpByteArray;
    QString retStr;
//    QTextCodec *gbk = QTextCodec::codecForName("gbk");

    QByteArray gbkBytes=hexStr.toLocal8Bit();
    qDebug() << "转换成gbk字节：" << gbkBytes;

    for (int i=0; i<gbkBytes.length()/4; i+= 4)
    {
        tmpStr = gbkBytes.mid(i,4);
        tmpByteArray = tmpStr.toLocal8Bit();
        bool ok;
        QChar* unicode = new QChar[1];
        unicode[0] = tmpByteArray.toInt(&ok,16);
        QString str = QString::fromRawData(unicode,1);
        qDebug() << str;
        retStr.append(str);
    }
}

float Utils::hexStrToFloat(QString &hexStr)
{
//    union str_u{
//      quint8 buf[4];
//      float f;
//    };
//    union str_u tmpUnio;
//    int j = 0;
//    for(int i=0; i<hexStr.length(); i+=2 ){
//        QString tmp0xStr = "0x" + hexStr.mid(i,2);

//        qDebug() << "tmp0xStr ： " << tmp0xStr;
//        tmpUnio.buf[j] =tmp0xStr.toInt(nullptr,16);
//        qDebug() << tmpUnio.buf[j];
//        j++;
//    }

    // windows 系统采用大端模式，高字节在前
    QString str = reverseStr(hexStr);
    int hex = str.toInt(0, 16);
    float value = *(float*)&hex;
    QString retStr = Utils::number(value,16);

    return value;
}

float Utils::hexStrToFloat(QByteArray &hexStr)
{
    QByteArray str =  reverseByteArr(hexStr);
    int hex = str.toInt(0, 16);
    float value = *(float*)&hex;
    return value;
}

double Utils::hexStrToFloat1(QString list)
{
    Utils::washPacket(list);
    if(list.length()!=8) { return 0;}

    bool ok;
    long sign = list.left(1).toLong(&ok,16)>>3;
    long Zsh = (list.left(3).toLong(&ok,16)  & 0x7F8)>>3;
    long Wsh = list.right(6).toLong(&ok,16)+0x800000;
    double ren = pow(-1,sign)*double(Wsh)*pow(2,(Zsh-150));

    return ren;
}

QString Utils::hexStrToIntStr(QString &hexStr)
{
    bool ok;
    QString ret;
    hexStr = Utils::reverseStr(hexStr);
    int dec = hexStr.toInt(&ok, 16);
    ret = QString::number(dec,10);

    return ret;
}

QString Utils::hexStrToIntStr(QByteArray &hexStr)
{
    bool ok;
    QString ret;
    hexStr = Utils::reverseByteArr(hexStr);
    qDebug() << "测试字节数组转int******";
    int dec = hexStr.toInt(&ok, 16);
    ret = QString::number(dec, 10);

    return ret;
}

QString Utils::FloatToHexStr(float value)
{
    int sign;
    QString S;
    double v;
    if((value)==0)
    {
        return "00000000" ;
    }
    else if((value)>0){
        sign=0;v=value;
    }
    else
    {
        sign=1;v=-value;
    }
    long zhishu=0;
    long weishu=0;
    if (v<1)
    {
        while(v<1){v=v*2;zhishu--; }
    }
    else
    {
        while(v>=2)
        {
            v=v/2;
            zhishu++;
        }
        zhishu = zhishu + 127;
        v=v-1;
        weishu=v*pow(2,23);
        weishu=weishu+(zhishu%2)*0x800000;
        zhishu=zhishu/2+sign*0x80;
        S=QString::number(zhishu,16)+QString::number(weishu,16);
    }

    return reverseStr(S.toUpper());
}

QString Utils::floatStrToHexStr(QString fStr)
{
    // 先将浮点数的字符串转换成浮点数
    return  FloatToHexStr(fStr.toFloat());
}

QString Utils::uintStrToHexStr(QString uiStr, int dataWidth)
{
    uint U1 = uiStr.toUInt();

    return  Utils::reverseStr(QString("%1").arg(U1,dataWidth,16,QLatin1Char('0')));
}


QString Utils::intToHexStr(int intput, int dataWidth)
{
    return  Utils::reverseStr(QString("%1").arg(intput, dataWidth,16,QLatin1Char('0')));
}

QString Utils::hexToAscii(const QString &hexStr)
{
    QString str_hex = hexStr;                //获取十六进制数
    int dec = str_hex.toInt(0,16);          //十六进制转十进制
    char st = dec;                       //十进制数用char类型表示--->必须有此步直接转化不可行
    QString str_ascii = QString(st);        //转化为ASCII值
   // int str_int = str_ascii.toInt();           //转化为int值

    return str_ascii;                       //返回十六进制符号的ascii码值
}

QString Utils::hexToAscii(const QByteArray &hexByte)
{
    QString str_hex = hexByte;                //获取十六进制数
    int dec = str_hex.toInt(0,16);          //十六进制转十进制
    char st = dec;                       //十进制数用char类型表示--->必须有此步直接转化不可行
    QString str_ascii = QString(st);        //转化为ASCII值
   // int str_int = str_ascii.toInt();           //转化为int值

    return str_ascii;
}

QStringList Utils::mixCharToWord(QString mixStr, int singleWidth)
{
    QStringList reList;
    for (int i=0; i< mixStr.length(); i+=singleWidth)
    {
         reList.append(mixStr.mid(i,singleWidth));
    }

    return reList;
}

QStringList Utils::mixCharToWord(QByteArray mixStr, int singleWidth)
{
    QStringList reList;
    for (int i=0; i< mixStr.count(); i += singleWidth)
    {
         reList.append(mixStr.mid(i, singleWidth));
    }

    return reList;
}

bool Utils::isPureNumStr(QString inputStr)
{
    QByteArray strByte = inputStr.toLatin1();
    char  *str = strByte.data();

    int i = 0,hex_flag = 0;
    if(strlen(str) == 0)
        return false;

    if((*str == '0')&&((*(str+1) == 'x')||(*(str+1) == 'X')))
        hex_flag = 1;
    for(i=0;i<(int)strlen(str);i++)
    {
        if(hex_flag)
        {
            if(strlen(str) == 2)
                return false;
            if((i > 1) && ( (*(str+i) < '0') || (*(str+i) > '9' && *(str+i) < 'A') || (*(str+i) > 'F' && *(str+i) < 'a') || (*(str+i) > 'f')))
                return false;
        }
        else
        {
            if((*(str+i) < '0') || (*(str+i) > '9'))
                return false;
        }
    }

    return true;
}


QString Utils::reverseStr(const QString &str)
{
    QString ret;
    //  00 00 80 3F
    for (int i=str.count(); i>=0; i -= 2)
    {
        ret.push_back(str.mid(i-2, 2));
    }

    return ret;
}

QByteArray Utils::reverseByteArr(const QByteArray &byteArr)
{
    QByteArray ret;
    //  0x00 0x00 0x80 0x3F  -> 0x3F 0x80 0x00 0x00
    for (int i=byteArr.count(); i>0; i -= 2)
    {
        ret.push_back(byteArr.mid(i-2, 2));
    }

    return ret;
}

QStringList Utils::parseFloatTypeMinMaxStep(const QString &str)
{
    QStringList resultList;
    for (int i=0; i<str.length(); i+=8 )
    {
        QString tmpStr = str.mid(i,8);
        //qDebug() << "浮点数量程： "<<Utils::hexStrToFloat(tmpStr);
        resultList.append( QString::number(Utils::hexStrToFloat(tmpStr)));
    }

    return  resultList;
}

QStringList Utils::parseFloatDimension(QByteArray &bytes)
{
    QStringList resultList;
    for (int i=0; i<bytes.count(); i += 8)
    {
        QByteArray tmpByte = bytes.mid(i, 8);
        resultList.append(QByteArray::number(Utils::hexStrToFloat(tmpByte)));
    }

    return resultList;
}

//A1 E3   (GID)数据~~~~~~~(GDD)数据1~~~~~~~~~~<ASCII8位码>:°
QString Utils::parseASCII8Bit(const QString &str, int wordWidth)
{
    QString result;
    // 从 str 中取提取出单次
    // 1个ASCII字符使用两个字符表示
    for (int i=0; i<str.length(); i += 2*wordWidth)
    {
        QString tmpStr = str.mid(i, 2*wordWidth);
        result.append( Utils::hexToAscii(tmpStr));
    }

    return  result;
}

QString Utils::parseASCII8BTypeMinMaxStepUnit(const QString &str)
{
    QString result;
    // 1个ASCII字符使用两个字符表示
    for (int i=0; i<str.length(); i += 2)
    {
        QString tmpStr = str.mid(i,2);
        result.append( Utils::hexToAscii(tmpStr));
    }

    return  result;
}

QString Utils::parseASCII8BTypeMinMaxStepUnit(const QByteArray &byte)
{
    QString result;
    // 1个ASCII字符使用两个字符表示
    for (int i=0; i<byte.length(); i += 2)
    {
        QByteArray tmpByte = byte.mid(i, 2);
        result.append(Utils::hexToAscii(tmpByte));
    }

    return  result;
}

void Utils::sleep(int msec)
{
    QTime n = QTime::currentTime();

    QTime now;
    do {
        now=QTime::currentTime();
    } while (n.msecsTo(now) <= msec);
}

int Utils::calNgdNo(QString &ngdStr)
{
    uint8_t ngd8B = ngdStr.toUInt(nullptr,16);

    return  ngd8B&0x3f;
}

int Utils::calNgdNo(QByteArray &ngdByte)
{
    uint8_t ngd = ngdByte.toUInt(nullptr, 16);

    return  ngd & 0x3f;
}


QString Utils::removeZero(QString &zeroStr)
{
    int str1 = zeroStr.toInt(nullptr, 10);
    return QString::number(str1, 16);
}

QByteArray Utils::removeZero(QByteArray &zeroBytes)
{
    int str1 = zeroBytes.toInt(nullptr, 10);
    return QByteArray::number(str1, 16);
}

int Utils::trans16CharTo10char(uchar &char16)
{
    bool ok;
    QString dataHex =  QString::number(char16);
    return dataHex.toInt(&ok, 16);
}

int Utils::binBytesToDecInt(QByteArray &binBytes)
{
    int ret = 0;
    for (int i=0; i<4; i++) {
        if ( binBytes.at(3-i) == '1') {
            ret +=  pow(2,i);
        }
    }

    return ret;
}

bool Utils::checkIpFormat(QString &ip)
{
    qDebug() <<"验证ip 地址格式" << ip;
    QRegExp rx("^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$");
    if(!rx.exactMatch(ip))
    {
        return false;
    }

    return true;
}

QStringList Utils::parseIntTypeMinMaxStep(const QString &str, int width)
{
    QStringList resultList;
    for (int i=0; i<str.length(); i+= width*2)
    {
        QString tmpStr = str.mid(i, width*2);
        tmpStr =  Utils::reverseStr(tmpStr);
        //            qDebug() << "--" << tmpStr;
        resultList.append( QString::number(tmpStr.toInt(nullptr,16)) );
    }

    return  resultList;
}

QStringList Utils::parseIntTypeMinMaxStep(const QByteArray &str, int width)
{
    QStringList resultList;
    for (int i=0; i<str.length(); i+= width*2)
    {
        QString tmpStr = str.mid(i, width*2);
        tmpStr =  Utils::reverseStr(tmpStr);
        resultList.append( QString::number(tmpStr.toInt(nullptr,16)) );
    }

    return  resultList;
}

QStringList Utils::parseUIntType(const QString &str, int singleWidth)
{
    QStringList resultList;
    //根据单个子字符占用长度切分
    //int countNum = str.length()/(singleWidth*2);
    QString tmpStr;
    for ( int i = 0; i< str.length(); i+=singleWidth*2 )
    {
        tmpStr = str.mid(i, singleWidth*2);         // 一个字节16进制hex字符使用两个字符表示
        resultList.append( QString::number(Utils::reverseStr(tmpStr).toInt(nullptr,16)) );
    }

    return  resultList;
}


QString Utils::hexStrToChineseStr(const QString &hexStr)
{
    // 文本转换编码器 从utf-8
    QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");

    // 设置utf-8编码到本地
    QTextCodec::setCodecForLocale(utf8);

    QTextCodec* gbk = QTextCodec::codecForName("gbk");

    //utf8 -> gbk
    //1. utf8 -> unicode
    QString strUnicode = utf8->toUnicode(hexStr.toLocal8Bit().data());

    //2. unicode -> gbk, 得到QByteArray
    QByteArray gb_bytes = gbk->fromUnicode(strUnicode);
    qDebug() << "unicode -> gbk" << gb_bytes;
    //gbk -> utf8
    //1. gbk to unicode
    strUnicode=gbk->toUnicode(hexStr.toLocal8Bit().data());

    //2. unicode -> utf-8
    QByteArray utf8_bytes=utf8->fromUnicode(strUnicode);
    qDebug() << "unicode-> utf-8" << utf8_bytes;
    return strUnicode;
}
